﻿using Serilog;
using sh3h.chuansha.job.Domain.Entities;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sh3h.chuansha.job.Jobs
{
    /// <summary>
    /// 同步电子发票作业
    /// </summary>
    public class SynInvoiceFileJob : BackgroundService
    {

        private readonly IConfiguration configuration;

        private readonly ISqlSugarClient db;

        public SynInvoiceFileJob(IConfiguration _configuration, ISqlSugarClient _db)
        {
            configuration = _configuration;
            db = _db;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            try
            {
                while (!stoppingToken.IsCancellationRequested)
                { 
                    Serilog.Log.Information("SynStockToThirdVendorJob running at: {time}", DateTimeOffset.Now);
                    Serilog.Log.Information("SynStockToThirdVendorJob begin");
                    await synVoid();
                    await Task.Delay(1000 * 60 * 3, stoppingToken);
                }
            }
            catch (OperationCanceledException)
            {
                // When the stopping token is canceled, for example, a call made from services.msc,
                // we shouldn't exit with a non-zero exit code. In other words, this is expected...
            }
            catch (Exception ex)
            {
                Serilog.Log.Error(ex, $" SynStockToThirdVendorJob {ex.Message}");

                // Terminates this process and returns an exit code to the operating system.
                // This is required to avoid the 'BackgroundServiceExceptionBehavior', which
                // performs one of two scenarios:
                // 1. When set to "Ignore": will do nothing at all, errors cause zombie services.
                // 2. When set to "StopHost": will cleanly stop the host, and log errors.
                //
                // In order for the Windows Service Management system to leverage configured
                // recovery options, we need to terminate the process with a non-zero exit code.
                Environment.Exit(1);
            }
        }

        private async Task synVoid()
        {

            string invoicePDFPath = configuration["InvoicePDFPath"].ToString();

            var noFileVatFPList = db.Queryable<FPVATFPMXEntity>()
                  .Where(u => u.D_KAIPIAORQ > DateTime.Now.AddDays(-10)
                  && string.IsNullOrEmpty(u.S_FTPPATH))
                  .ToList();

            foreach (var item in noFileVatFPList)
            {
                try
                {
                    string destinationFilePath = invoicePDFPath + "/" + Convert.ToDateTime(item.D_KAIPIAORQ).ToString("yyyyMM") + "/" + item.S_FILENAME;
                    string url = item.S_URL;
                    HttpClient client = new HttpClient();

                    using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                    {
                        response.EnsureSuccessStatusCode();
                        using (var contentStream = await response.Content.ReadAsStreamAsync())
                        using (var fileStream = new FileStream(destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            await contentStream.CopyToAsync(fileStream);
                        }
                    }

                    if (File.Exists(destinationFilePath))
                    {
                        item.S_FTPPATH = $"ftp://180.168.129.2:13227/{Convert.ToDateTime(item.D_KAIPIAORQ).ToString("yyyyMM")}/{item.S_FILENAME}";
                        db.Updateable(item).UpdateColumns(u => new { u.S_FTPPATH }).ExecuteCommand();
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "download file error");
                }
            }
        }
    }
}
